########################################################################
#  Searx-Qt - Lightweight desktop application for Searx.
#  Copyright (C) 2020-2024  CYBERDEViL
#
#  This file is part of Searx-Qt.
#
#  Searx-Qt is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  Searx-Qt is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
########################################################################

from PyQt5.QtCore import QTimer

from searxqt.core import log
from searxqt.core.http import HttpThread


class _ThreadManager:
    Tick = 200
    MaxIdleTicks = 20  # 4 seconds with 200ms tick rate

    def __init__(self):
        self._thread = None
        self._openCount = 0
        self._idleTicks = 0
        self._timer = QTimer()
        self._timer.timeout.connect(self.updateState)

    @property
    def thread(self):
        return self._thread

    def get(self, response):
        if self.thread is None:
            self.start()

        self._openCount += 1
        self.thread.get(response)

    def cancelAll(self):
        if self.thread is not None:
            self.thread.cancelAll()
        self._openCount = 0

    def start(self):
        if self.thread is not None:
            log.error("start() 'self.thread is not None'.", self)
            return

        self._thread = HttpThread()
        self._openCount = 0
        self._idleTicks = 0
        self.thread.start()
        self._timer.start(self.Tick)
        log.debug("Http.Thread started")

    def stop(self):
        self.thread.cancelAll()
        self.thread.exit()
        self._timer.stop()
        self._openCount = 0
        self._idleTicks = 0
        self._thread = None
        log.debug("Http.Thread stopped")

    def updateState(self):
        if not self.thread:
            return
        n = self.thread.processCallbacks()
        self._openCount -= n
        if self._openCount == 0:
            if self._idleTicks == self.MaxIdleTicks:
                self.stop()
                return
            self._idleTicks += 1
        else:
            self._idleTicks = 0

    def exitAndJoin(self):
        if not self.thread:
            return

        self.thread.cancelAll()
        self.thread.exit()
        self.thread.join()
        self._thread = None

Thread = _ThreadManager()



